package gui;

import java.util.Random;
import processing.core.PApplet;

public class Color {
	// Utilty class
	// color utilities by Neil Banas
	private Color() {	
	}
	
	private static int color(int r, int g, int b, int a) {	 	
		// Packs four 8 bit numbers into one 32 bit number
		a = a << 24;  
		r = r << 16;  
		g = g << 8;   
		return a | r | g | b;
	}

	private static int color(float r, float g, float b, float a) {	 	
		// Packs four 8 bit numbers into one 32 bit number
		return color((int)r, (int)g, (int)b, (int)a);
	}

	private static int alpha(int myColor) {
		return (myColor >> 24) & 0xFF;
	}

	private static int red(int myColor) {
		return (myColor >> 16) & 0xFF;
	}

	private static int green(int myColor) {
		return (myColor >> 8) & 0xFF;
	}

	private static int blue(int myColor) {
		return myColor & 0xFF;
	}
	
	public static int colorblend(int c1, int c2, double r) {
	  return color(PApplet.lerp(red(c1), red(c2), (float)r),
	  	  	       PApplet.lerp(green(c1), green(c2), (float)r),
		           PApplet.lerp(blue(c1), blue(c2), (float)r),
			       PApplet.lerp(alpha(c1), alpha(c2), (float)r));
	}

	static int shift(int col, float r) {
	    if (r>0) {
	        return colorblend(col, color(255, 255, 255, alpha(col)), r);
	    } else {
	        return colorblend(col, color(0, 0, 0, alpha(col)), -r);
  	    }
	}

	int lighten(int col) {return shift(col, (float)0.25);}

	static int darken(int col) {return shift(col, (float)-0.25);}

	int randomshift(int col) {
		Random random = new Random();
	    return shift(col, random.nextFloat()-(float)0.5);
	}

	int colorinterp(float val, float lowval, float highval, int[] cmap) {
	    return colorinterp(val, lowval, highval, cmap, "nearest");
	}
		
	int colorinterp(float val, float lowval, float highval, int[] cmap, String mode) {
		if (mode.equals("linear")) {
		    float level = PApplet.constrain((float)((val - lowval)/(highval - lowval)), (float)0, (float)(1-1e-6)) * cmap.length;
		    int level0 = PApplet.floor((float) level);
		    int level1 = PApplet.constrain(PApplet.ceil(level), 0, cmap.length-1);
		    return colorblend(cmap[level0], cmap[level1], level-level0);
		} 
		else {
		    int level = PApplet.floor(PApplet.constrain((float)((val-lowval)/(highval-lowval)), 
		    		                                    (float)0, 
		    		                                    (float)(1-1e-6)) * cmap.length);
		    return cmap[level];
	    }
	}

}
